package com.xneure.utils.http;

import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

public abstract class HttpDebugger<Obj> {
	public enum HttpType {
		POST, GET;
	}

	protected ContentType defaultType = ContentType.create("application/json", "utf-8");
	protected Charset defaultCharset = Consts.UTF_8;
	private String url;
	private Map<String, String> param;
	protected Obj entity;
	private HttpRequestBase httpRequest;

	public HttpDebugger(HttpType type) {
		setHttpRequestType(type);
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public abstract Obj getEntity();

	public Map<String, String> getParam() {
		return param;
	}

	public void setParam(Map<String, String> param) {
		this.param = param;
	}

	public void addParam(String name, String value) {
		if (null == param) {
			param = new LinkedHashMap<String, String>(20);
		}
		param.put(name, value);
	}

	public void addCookie(String key, String value) {
		httpRequest.addHeader("Cookie", key.concat("=").concat(value));
	}

	public void addHeader(String key, String value) {
		httpRequest.addHeader(key, value);
	}

	public HttpRequestBase getHttpRequest() {
		return httpRequest;
	}

	public void clearData() {
		entity = null;
	}

	protected HttpClient createHttpClient() {
		return HttpClientBuilder.create().build();
	}

	public void setHttpRequestType(HttpType type) {
		switch (type) {
		case POST:
			httpRequest = new HttpPost();
			break;
		case GET:
			httpRequest = new HttpGet();
			break;
		default:
			break;
		}
	}

	public String responseToString(HttpResponse execute) {
		try {
			return EntityUtils.toString(execute.getEntity(), defaultCharset);
		} catch (IOException e) {
			return null;
		}
	}

	protected String buildUrl() {
		if (null != param) {
			StringBuilder urlAddres = new StringBuilder(url);
			urlAddres.append("?");
			for (Map.Entry<String, String> ent : param.entrySet()) {
				urlAddres.append(ent.getKey()).append("=").append(ent.getValue()).append("&");
			}
			return urlAddres.substring(0, urlAddres.length() - 1);
		} else {
			return url;
		}
	}

	protected HttpEntity loadEntity() {
		return (HttpEntity) entity;
	}

	protected HttpResponse execute() {
		httpRequest.setURI(URI.create(buildUrl()));
		if (HttpPost.class.equals(httpRequest.getClass()) && entity != null) {
			((HttpEntityEnclosingRequest) httpRequest).setEntity(loadEntity());
		}
		HttpClient httpClient = createHttpClient();
		try {
			return httpClient.execute(httpRequest);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	protected HttpResultProvider execute2() {
		return new HttpResultProvider(execute());
	}

	public HttpResponse sendPost() {
		return execute();
	}

	public HttpResponse sendGet() {
		return execute();
	}

	public HttpResultProvider sendPost2() {
		if (httpRequest.getMethod().equals("POST") == false) {
			throw new RuntimeException("请求类型不是POST");
		}
		return execute2();
	}

	public HttpResultProvider sendGet2() {
		if (httpRequest.getMethod().equals("GET") == false) {
			throw new RuntimeException("请求类型不是GET");
		}
		return execute2();
	}
}
